﻿using Encryption.Base;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Encryption.Utility
{
    public enum MyEnum
    {
        PKCS1,
        PKCS8
    }
    class Rsa : CommonUtilityBase
    {
        
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void GenerateKey(int a, ref byte b, MyEnum c , string d);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void EncryptByPublicKey(byte[] a, ref byte b, string d, MyEnum c);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void EncryptByPraviteKey(byte[] a, ref byte b, string d, MyEnum c);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void DecodeByPraviteKey(string a, ref byte b, string d, MyEnum c);

        private string m_rsaGenerateKey;
        private string m_encryptByPublicKey;
        private string m_encryptByPraviteKey;
        private string m_decodeByPraviteKey;
        public Rsa()
        {
            m_rsaGenerateKey = "GenerateKey";
            m_encryptByPublicKey = "EncryptByPublicKey";
            m_encryptByPraviteKey = "EncryptByPraviteKey";
            m_decodeByPraviteKey = "DecodeByPraviteKey";
        }

        public string[] RsaGenerateKey(int keyLen,MyEnum myEnum, string password)
        {
            if (GetPublicDll() == IntPtr.Zero)
                return null;
            GenerateKey generateKey = (GenerateKey)GetFunction(m_rsaGenerateKey, typeof(GenerateKey));
            byte[] o = new byte[5120];
            generateKey(keyLen, ref o[0], myEnum, password);
            string w = Encoding.UTF8.GetString(o);
            JObject jo = JObject.Parse(Encoding.UTF8.GetString(o));
            string[] values = jo.Properties().Select(item => item.Value.ToString()).ToArray();
            return values;
        }

        public string RsaEncryptByPublicKey(string in_str, string pubKey, MyEnum myEnum)
        {
            if (GetPublicDll() == IntPtr.Zero)
                return "";
            EncryptByPublicKey encryptByPublicKey = (EncryptByPublicKey)GetFunction(m_encryptByPublicKey, typeof(EncryptByPublicKey));
            byte[] o = new byte[5120];
            string y = "";
            encryptByPublicKey(Encoding.UTF8.GetBytes(in_str), ref o[0], pubKey, myEnum);
            string w = Encoding.UTF8.GetString(o).Replace("\n", "").Replace("\0", "");
            return w;
        }

        public string RsaEncryptByPraviteKey(string in_str, string pubKey, MyEnum myEnum)
        {
            if (GetPublicDll() == IntPtr.Zero)
                return "";
            EncryptByPraviteKey encryptByPraviteKey = (EncryptByPraviteKey)GetFunction(m_encryptByPraviteKey, typeof(EncryptByPraviteKey));
            byte[] o = new byte[5120];
            string y = "";
            encryptByPraviteKey(Encoding.UTF8.GetBytes(in_str), ref o[0], pubKey, myEnum);
            string w = Encoding.UTF8.GetString(o).Replace("\n", "").Replace("\0", "");
            return w;
        }

        public string RsaDecodeByPraviteKey(string in_str, string pubKey, MyEnum myEnum)
        {
            if (GetPublicDll() == IntPtr.Zero)
                return "";
            DecodeByPraviteKey decodeByPraviteKey = (DecodeByPraviteKey)GetFunction(m_decodeByPraviteKey, typeof(DecodeByPraviteKey));
            byte[] o = new byte[5120];
            string y = "";
            decodeByPraviteKey(in_str, ref o[0], pubKey, myEnum);
            string w = Encoding.UTF8.GetString(o).Replace("\n", "").Replace("\0", "");
            return w;
        }
    }
}
